package cn.t.service.user;

import cn.t.constants.CommonConstants;
import cn.t.constants.Constants;
import cn.t.core.enums.base.BaseStatusEnum;
import cn.t.core.exception.BizException;
import cn.t.core.mode.YesNoEnum;
import cn.t.core.service.ServiceImpl;
import cn.t.core.enums.base.CommonError;
import cn.t.model.user.CostCenterDO;
import cn.t.repository.user.CostCenterRepository;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static cn.t.constants.Constants.REDIS_KEY__COST_CENTER;


/**
 * 场景信息表领域服务
 *
 * @author l
 */
@Slf4j
@Service
@AllArgsConstructor
public class CostCenterService extends ServiceImpl<CostCenterDO, CostCenterRepository> {


    @Override
    public boolean update(CostCenterDO costCenterDO) {
        boolean result = super.update(costCenterDO);
        redissonClient.getBucket(String.format(REDIS_KEY__COST_CENTER, costCenterDO.getId())).delete();
        return result;
    }

    @Override
    public CostCenterDO findById(Long id) {
        String redisKey = String.format(REDIS_KEY__COST_CENTER, id);
        CostCenterDO result = (CostCenterDO) redissonClient.getBucket(redisKey).get();
        if (result != null && result.getId() != null && result.getId().equals(id)) {
            return result;
        }

        result = super.findById(id);
        redissonClient.getBucket(redisKey).set(result, 1, TimeUnit.HOURS);

        return result;
    }

    public List<CostCenterDO> getCostCenterList(List<Long> ids) {
        return repository.getCostCenterList(ids);
    }


    public void isValidCostCenter(Long costCenterId, Long firmId) {
        if (costCenterId == null || firmId == null) {
            return;
        }

        CostCenterDO costCenter = findById(costCenterId);

        if (costCenter == null || costCenter.getId() == null || !costCenter.getId().equals(costCenterId)) {
            String errorMessage = String.format("指定的成本中心不存在 costCenterId=%s ", costCenterId);
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        if (firmId != null && !costCenter.getFirmId().equals(firmId)) {
            String errorMessage = String.format("指定的成本中心不存在 costCenterId=%s firmId=%s", costCenter.getId(), firmId);
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);

        }
    }

    public List<CostCenterDO> findByFirm(List<Long> firmIds) {
        CostCenterDO template = new CostCenterDO();
        template.setFirmIds(firmIds);
        template.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));
        template.setIsDeleted(YesNoEnum.FALSE);
        return repository.findByModel(template, 0, 10000, "cost_center_code", "asc");
    }

    public Map<Long, String> getCostCenterIdNameMap(List<Long> costCenterIds) {
        CostCenterDO queryParams = new CostCenterDO();
        queryParams.setCostCenterIds(costCenterIds);
        List<CostCenterDO> costCenters = this.findByModel(queryParams, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);

        Map<Long, String> costCenterIdNameMap = new HashMap<>();
        costCenters.forEach(costCenter -> costCenterIdNameMap.put(costCenter.getId(), costCenter.getCostCenterName()));
        return costCenterIdNameMap;
    }

    public List<CostCenterDO> findCostCenterByNameAndFirm(String costCenterName, Long firmId) {

        String redisKey = String.format(Constants.REDIS_KEY__COST_CENTER__NAME_WITH_FIRM_ID, costCenterName, firmId);

        if (redissonClient.getBucket(redisKey).isExists()) {
            return (List<CostCenterDO>) redissonClient.getBucket(redisKey).get();
        }

        CostCenterDO template = new CostCenterDO();

        template.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));
        template.setIsDeleted(YesNoEnum.FALSE);
        template.setFirmId(firmId);
        template.setCostCenterNameAll(costCenterName);

        List<CostCenterDO> result = repository.findByModel(template, 0, 100, "id", "asc");

        if (!CollectionUtils.isEmpty(result)) {
            redissonClient.getBucket(redisKey).set(result, 5, TimeUnit.MINUTES);
        }
        return result;

    }

    public List<CostCenterDO> findByCostCenterCode(Long firmId, String costCenterCode) {
        CostCenterDO template = new CostCenterDO();
        template.setFirmId(firmId);
        template.setCostCenterCode(costCenterCode);
        template.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));
        template.setIsDeleted(YesNoEnum.FALSE);
        return repository.findByModel(template, 0, 10000, "cost_center_code", "asc");
    }

    public List<CostCenterDO> findByName(Long firmId, String costCenterName) {
        CostCenterDO template = new CostCenterDO();
        template.setFirmId(firmId);
        template.setCostCenterName(costCenterName);
        template.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));
        template.setIsDeleted(YesNoEnum.FALSE);
        return repository.findByModel(template, 0, 10000, "cost_center_name", "asc");
    }

    @Autowired
    private RedissonClient redissonClient;


}
